import math
import os
import shutil
from typing import final

import pandas as pd
from pandas import Series

pd.set_option('display.unicode.east_asian_width', True)

BASE_5G生态应用技术 = "D:/100-Project/2024-2025-2学期安排/武昌首义学院/14301292_《5G生态应用技术（企业）》"


#########################################################################################

#########################################################################################

def get_filenames(path):
    filenames = []
    for file in os.listdir(path):
        if file.endswith('.docx'):  # 如果文件以'.txt'结尾
            filenames.append(file)
    return filenames


def 检查路径名(filenames):
    l = []
    for filename in filenames:
        if len(filename.split('.')) < 3:
            l.append(filename)

    if len(l) != 0:
        for e in l:
            print(e)
        exit(1)


def 统计时间信息(path) -> Series:
    filenames = get_filenames(path)
    检查路径名(filenames)

    l = []
    for filename in filenames:
        date = filename.split('.')[1]
        l.append(date)

    se = pd.Series(l)
    se.drop_duplicates(inplace=True)
    se.sort_values(inplace=True)
    return se


def _truncate(filename) -> list:
    li = filename.split('.')
    if len(li) < 3:
        print(filename)
        exit(0)
    return li


def truncate_id(filename) -> str:
    li = _truncate(filename)
    return li[0].split('-')[1]


def truncate_name(filename) -> str:
    li = _truncate(filename)
    return li[0].strip('-').split('-')[2]


def truncate_date(filename) -> str:
    li = _truncate(filename)
    return li[1]


def truncate_name_date(filename) -> tuple[str, str]:
    name = truncate_name(filename)
    date = truncate_date(filename)
    return name, date


def convert_xxyy_to_date(strings):
    """
    在之前的操作中，我们可以从文件的路径名中获得日期字符串，形如 5024。
    现在通过本方法将字符串 0524 转换为更为标准的字符串形式，形如 2025-05-24。
    在其中年份 2025 是硬编码指定的。

    参数:
        strings (list): "xxyy" 格式的字符串列表
    返回:
        list: 转换后的日期字符串列表
    """
    converted = []

    for s in strings:
        # 验证输入格式
        if len(s) != 4 or not s.isdigit():
            # 无效格式处理：保留原样或标记错误
            converted.append(f"INVALID: {s}")
            continue

        # 提取月份和年份部分
        month = s[:2]  # 前两位是月份
        year = s[2:]  # 后两位是年份

        # 转换为目标格式
        date_str = f"2025-{month}-{year}"
        converted.append(date_str)

    return converted


from datetime import datetime, timedelta


def calculate_date_scores(date_list, date_format="%Y-%m-%d", base_score=25):
    """
    计算日期数组中每个日期的评分

    参数:
        date_list (list): 日期字符串列表（从小到大有序）
        date_format (str): 日期格式字符串，默认为 "%Y-%m-%d"
        base_score (int): 基础分数，默认为25分

    返回:
        list: 与输入日期顺序对应的分数列表
    """
    # 处理空列表情况
    if not date_list:
        return []

    dates = []
    # 转换日期字符串为datetime对象
    try:
        dates = [datetime.strptime(date_str, date_format) for date_str in date_list]
    except ValueError as e:
        raise ValueError(f"日期格式错误: {str(e)}") from e

    # 获取基准日期（最早日期）
    base_date = dates[0]

    # 计算每个日期的分数
    scores = []
    for date in dates:
        # 计算与基准日期的间隔天数
        delta = date - base_date
        days_diff = delta.days

        # 计算分数：基础分 - 间隔天数
        score = base_score - math.floor(days_diff * 0.5)
        if score <= 0:
            score = 2
        else:
            score = score
        scores.append(score)

    return scores


import pandas as pd
import os


def merge_student_scores(excel_path, student_ids, scores, output_path=None, student_id_col='学号',
                         new_score_col='成绩'):
    """
    将学生成绩合并到学生信息Excel中

    参数:
        excel_path (str): 学生信息Excel文件路径
        student_ids (list): 学生学号列表
        scores (list): 对应学号的成绩列表
        output_path (str): 输出文件路径（默认在原始文件基础上添加后缀）
        student_id_col (str): 学号列名（默认为'学号'）
        new_score_col (str): 新增成绩列名（默认为'成绩'）

    返回:
        str: 输出文件路径
    """
    try:
        # 1. 读取原始学生信息Excel
        df_original = pd.read_excel(excel_path)

        # 2. 创建成绩DataFrame
        df_scores = pd.DataFrame({
            student_id_col: student_ids,
            new_score_col: scores
        })

        # 3. 合并数据（左连接，保留所有学生信息）
        df_merged = pd.merge(
            df_original,
            df_scores,
            on=student_id_col,
            how='left'
        )

        # 4. 处理输出路径
        if output_path is None:
            # 默认在原始文件名后添加 "_带成绩"
            dir_name, file_name = os.path.split(excel_path)
            name, ext = os.path.splitext(file_name)
            output_path = os.path.join(dir_name, f"{name}_带成绩{ext}")

        # 5. 保存结果
        df_merged.to_excel(output_path, index=False)

        print(f"✅ 成绩合并完成! 文件已保存至: {output_path}")
        print(f"总学生数: {len(df_original)}")
        print(f"有成绩学生数: {len(df_scores)}")
        print(f"缺失成绩学生数: {len(df_merged[df_merged[new_score_col].isna()])}")

        return output_path

    except Exception as e:
        print(f"❌ 合并失败: {str(e)}")
        raise


def fill_empty_cells(input_file, output_file=None, start_col=1, end_col=6, fill_value=0):
    """
    将Excel中指定列的空缺数据填充为0

    参数:
        input_file (str): 输入Excel文件路径
        output_file (str): 输出Excel文件路径（默认覆盖原文件）
        start_col (int): 起始列索引（从0开始，第3列对应索引2）
        end_col (int): 结束列索引（第6列对应索引5）
        fill_value: 填充值（默认为0）
    """
    try:
        # 读取Excel文件
        df = pd.read_excel(input_file)

        # 获取列名列表
        columns = df.columns.tolist()

        # 验证列索引范围
        if start_col < 0 or end_col >= len(columns) or start_col > end_col:
            raise ValueError(f"列索引范围无效: start_col={start_col}, end_col={end_col}, 总列数={len(columns)}")

        # 选择需要填充的列范围（第3到第6列）
        target_columns = columns[start_col:end_col + 1]  # +1 因为切片是左闭右开

        print(f"将填充以下列的空缺数据: {target_columns}")

        # 填充指定列的空值为0
        df[target_columns] = df[target_columns].fillna(fill_value)

        # 处理输出路径
        if output_file is None:
            output_file = input_file  # 覆盖原文件
            print("⚠️ 注意: 将覆盖原始文件")

        # 保存结果
        df.to_excel(output_file, index=False)
        print(f"✅ 空缺数据填充完成! 文件已保存至: {output_file}")

        # 返回填充后的DataFrame
        return df

    except Exception as e:
        print(f"❌ 处理失败: {str(e)}")
        raise


def read_specific_columns(file_path, columns, dtype, header_row, converters):
    """
    从Excel文件中读取指定列的数据

    参数:
        file_path (str): Excel文件路径
        columns (list): 要读取的列索引列表（从0开始计数）
        header_row (int): 标题行索引（默认为0，即第一行）

    返回:
        pd.DataFrame: 包含指定列数据的DataFrame
    """

    try:
        # 读取Excel文件中的指定列
        df = pd.read_excel(file_path, usecols=columns, dtype=dtype, header=header_row, converters=converters)

        # 打印读取的信息
        print(f"✅ 成功读取文件: {file_path}")
        print(f"读取的列: {df.columns.tolist()}")
        print(f"总行数: {len(df)}")

        return df

    except Exception as e:
        print(f"❌ 读取失败: {str(e)}")
        raise
